package com.milkshopbackend.milkshop.Service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.milkshopbackend.milkshop.Service.ProductSearchService;
import com.milkshopbackend.milkshop.common.RedisConstants;
import com.milkshopbackend.milkshop.entity.Product;
import com.milkshopbackend.milkshop.entity.ProductDTO;
import com.milkshopbackend.milkshop.entity.ProductSearchDTO;
import com.milkshopbackend.milkshop.mapper.ProductMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.data.redis.core.RedisTemplate;
import java.util.concurrent.TimeUnit;
import java.util.List;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
@Slf4j
public class ProductSearchServiceImpl extends ServiceImpl<ProductMapper, Product> implements ProductSearchService {
    private final ProductMapper productMapper;
    private final RedisTemplate<String, Object> redisTemplate;

    /**
     * 处理搜索关键词
     * @param keyword 原始关键词
     * @return 处理后的关键词
     */
    private String processKeyword(String keyword) {
        if (!StringUtils.hasText(keyword)) {
            return null;
        }
        
        // 1. 去除首尾空格
        keyword = keyword.trim();
        
        // 2. 去除特殊字符，只保留中文、英文、数字
        keyword = keyword.replaceAll("[^\\w\\u4e00-\\u9fa5]", "");
        
        // 3. 去除重复空格
        keyword = keyword.replaceAll("\\s+", " ");
        
        // 4. 关键词长度限制
        if (keyword.length() > 50) {
            keyword = keyword.substring(0, 50);
        }
        
        return keyword;
    }

    @Override
    public IPage<ProductDTO> search(ProductSearchDTO searchDTO) {
        // 处理搜索关键词
        String processedKeyword = processKeyword(searchDTO.getKeyword());
        searchDTO.setKeyword(processedKeyword);

        // 统计关键词热度
        if (StringUtils.hasText(processedKeyword)) {
            redisTemplate.opsForZSet().incrementScore(RedisConstants.HOT_SEARCH_KEY, processedKeyword, 1);
        }

        // 判断是否为热门关键词
        boolean isHot = false;
        if (StringUtils.hasText(processedKeyword)) {
            // 获取前N个热门关键词
            List<String> hotKeywords = redisTemplate.opsForZSet()
                .reverseRange(RedisConstants.HOT_SEARCH_KEY, 0, RedisConstants.HOT_SEARCH_TOP_N - 1)
                .stream().map(Object::toString).collect(Collectors.toList());
            if (hotKeywords.contains(processedKeyword)) {
                isHot = true;
            }
        }

        // 如果是热门关键词，尝试查缓存
        String cacheKey = null;
        if (isHot) {
            cacheKey = "milk:product:search:hot:" + processedKeyword + ":page:" + searchDTO.getPageNum() + ":size:" + searchDTO.getPageSize();
            Object cache = redisTemplate.opsForValue().get(cacheKey);
            if (cache != null && cache instanceof IPage) {
                return (IPage<ProductDTO>) cache;
            }
        }

        // 构建查询条件
        LambdaQueryWrapper<Product> wrapper = new LambdaQueryWrapper<>();
        
        // 关键词搜索
        if (StringUtils.hasText(processedKeyword)) {
            wrapper.and(w -> w
                .like(Product::getName, processedKeyword)
                .or()
                .like(Product::getDescription, processedKeyword)
            );
        }
        
        // 分类搜索
        if (searchDTO.getCategoryId() != null) {
            wrapper.eq(Product::getCategoryId, searchDTO.getCategoryId());
        }
        
        // 价格区间搜索
        if (searchDTO.getMinPrice() != null) {
            wrapper.ge(Product::getPrice, searchDTO.getMinPrice());
        }
        if (searchDTO.getMaxPrice() != null) {
            wrapper.le(Product::getPrice, searchDTO.getMaxPrice());
        }
        
        // 评分搜索
        if (searchDTO.getMinRating() != null) {
            wrapper.ge(Product::getRating, searchDTO.getMinRating());
        }
        
        // 排序
        if (StringUtils.hasText(searchDTO.getSortField())) {
            String sortField = searchDTO.getSortField();
            if ("price".equals(sortField)) {
                wrapper.orderBy(true, "asc".equalsIgnoreCase(searchDTO.getSortOrder()), Product::getPrice);
            } else if ("rating".equals(sortField)) {
                wrapper.orderBy(true, "asc".equalsIgnoreCase(searchDTO.getSortOrder()), Product::getRating);
            } else if ("sales".equals(sortField)) {
                wrapper.orderBy(true, "asc".equalsIgnoreCase(searchDTO.getSortOrder()), Product::getSales);
            }
        } else {
            // 默认按创建时间倒序
            wrapper.orderByDesc(Product::getCreateTime);
        }
        
        // 分页查询
        Page<Product> page = new Page<>(searchDTO.getPageNum(), searchDTO.getPageSize());
        IPage<Product> productPage = productMapper.selectPage(page, wrapper);
        
        // 转换为DTO
        IPage<ProductDTO> result = productPage.convert(product -> {
            ProductDTO dto = new ProductDTO();
            BeanUtils.copyProperties(product, dto);
            return dto;
        });

        // 如果是热门关键词，写入缓存
        if (isHot && cacheKey != null) {
            redisTemplate.opsForValue().set(cacheKey, result, RedisConstants.HOT_SEARCH_RESULT_TTL, TimeUnit.SECONDS);
        }
        return result;
    }

    private SFunction<Product, ?> getColumn(String field) {
        switch (field) {
            case "price":
                return Product::getPrice;
            default:
                return Product::getCreateTime;
        }
    }
}